/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package instantmessengercpsc360.server;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author nicholas
 */
public class ClientManager implements Runnable, ServerListUpdateEventListener {

    public ClientManager(ServerMainFrame parent, Integer port) throws IOException {
        skt = new ServerSocket(port);
        running = true;
        this.parent = parent;
    }
    
    protected ServerMainFrame parent;
    protected ServerSocket skt;
    protected ArrayList<ClientWrapper> clients  = new ArrayList<ClientWrapper>();
    public final ReentrantLock clientsLock = new ReentrantLock();
    protected Boolean running;
    

    @Override
    public void run() {
        while (running)
        {
            try {
                Socket ncl = skt.accept();
                //TODO lock the client list to verify username uniqueness
                //Creates a new client thread to handle the listening
                ClientWrapper cw = new ClientWrapper(this, ncl);
                cw.addServerListUpdateEventListener(this);
                cw.addServerListUpdateEventListener(parent);
                clients.add(cw);
                new Thread(cw).start();
                
            } catch (IOException ex) {
                if (running)
                    Logger.getLogger(ClientManager.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public void terminate()
    {
        try {
            running = false;
            for (ClientWrapper cw : clients)
                cw.terminate();
            skt.close();
        } catch (IOException ex) {
            Logger.getLogger(ClientManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public ClientWrapper getClient(String s)
    {
        for (ClientWrapper cw : clients)
        {
            if (cw.toString().equals(s))
                return cw;
        }
        throw new RuntimeException("Could not find client: " + s);
    }
    
    /**
     * Sends an update to the client with the newly added/deleted client.
     * @param evt 
     */
    @Override
    public void ServerListUpdateEventOccurred(ServerListUpdateEvent evt) {
        for (ClientWrapper cw : clients)
        {
            if (!(cw.getUsername() == null))
                if (!cw.equals(evt.getSource()))
                    cw.postUpdateToClientList(evt);
        }
    }
    
    //TODO custom event for adding clients to list
    //TODO custom event for managing conversations
        //add
        //delete
        //edit? later...

    @Override
    public String toString() {
        return clients.toString();
    }
}
